package me.zhengjie.modules.website.service.impl;



import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import me.zhengjie.modules.website.domain.ArchiveInformation;
import me.zhengjie.modules.website.repository.ArchiveInformationRepository;
import me.zhengjie.modules.website.repository.ArchiveInformationSpecifications;
import me.zhengjie.modules.website.service.ArchiveInformationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import me.zhengjie.modules.website.domain.PageResult;
import org.springframework.web.multipart.MultipartFile;

import javax.persistence.criteria.Predicate;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * @author system
 * @since 2024-11-05 23:38:48
 */
@Service
public class ArchiveInformationServiceImpl implements ArchiveInformationService {

    @Autowired
    private ArchiveInformationRepository archiveInformationRepository;

    @Override
    public PageResult<ArchiveInformation> findPage(ArchiveInformation params, LocalDateTime startDate, LocalDateTime endDate, Pageable pageable) {
        Page<ArchiveInformation> page = archiveInformationRepository.findAll((root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();

            // 使用反射遍历 ArchiveInformation 的字段，过滤静态字段和非持久化字段
            for (Field field : ArchiveInformation.class.getDeclaredFields()) {
                field.setAccessible(true);
                if (Modifier.isStatic(field.getModifiers())) {
                    continue;
                }

                try {
                    Object value = field.get(params);
                    if (value != null) {
                        // 如果是 title 字段，使用模糊匹配
                        if ("title".equals(field.getName())) {
                            predicates.add(criteriaBuilder.like(root.get(field.getName()), "%" + value + "%"));
                        } else {
                            // 对其他字段使用精确匹配
                            predicates.add(criteriaBuilder.equal(root.get(field.getName()), value));
                        }
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }

            // 时间范围条件，使用 documentTime 字段进行比较
            if (startDate != null) {
                predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("documentTime"), Timestamp.valueOf(startDate)));
            }
            if (endDate != null) {
                predicates.add(criteriaBuilder.lessThanOrEqualTo(root.get("documentTime"), Timestamp.valueOf(endDate)));
            }

            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        }, pageable);

        PageResult<ArchiveInformation> result = new PageResult<>();
        result.setContent(page.getContent());
        result.setTotalElements(page.getTotalElements());
        return result;
    }


    @Override
    public PageResult<ArchiveInformation> findPage(ArchiveInformation archiveInformation, Pageable pageable) {
        Page<ArchiveInformation> page = archiveInformationRepository.findAll(ArchiveInformationSpecifications.queryList(archiveInformation), pageable);
        PageResult<ArchiveInformation> result = new PageResult();
        result.setContent(page.getContent());
        result.setTotalElements(page.getTotalElements());
        return result;
    }

    @Override
    public List<ArchiveInformation> findList(ArchiveInformation archiveInformation) {
        return archiveInformationRepository.findAll(ArchiveInformationSpecifications.queryList(archiveInformation));
    }

    @Override
    public ArchiveInformation findById(Long id) {
        return archiveInformationRepository.findById(id).orElse(null);
    }

    @Override
    public ArchiveInformation insert(ArchiveInformation archiveInformation) {
        return archiveInformationRepository.save(archiveInformation);
    }

    @Override
    public ArchiveInformation update(ArchiveInformation archiveInformation) {
        return archiveInformationRepository.saveAndFlush(archiveInformation);
    }

    @Override
    public void delete(Long id) {
        archiveInformationRepository.deleteById(id);
    }


    @Override
    public List<ArchiveInformation> importExcel(MultipartFile file) throws Exception {
        if (file.isEmpty()) {
            throw new IllegalArgumentException("文件不能为空");
        }
        InputStream inputStream = file.getInputStream();
        return EasyExcel.read(inputStream, ArchiveInformation.class, new ReadListener<ArchiveInformation>() {
            private List<ArchiveInformation> list = new ArrayList<>();

            @Override
            public void invoke(ArchiveInformation data, AnalysisContext context) {
                list.add(data);
            }

            @Override
            public void doAfterAllAnalysed(AnalysisContext context) {
                archiveInformationRepository.saveAll(list);
            }
        }).sheet().doReadSync();
    }
}